import math

import pygame
from pygame.math import clamp

from per.mnxc.survival_evolution.constants.constants import VIEW_MAX, SPEED_MAX, ENERGY_CONSUME, ENERGY_CONVERT, \
    PLANT_ENERGY_INIT, PLANT_ENERGY_CONSUME, WORLD_WIDTH, WORLD_HEIGHT, ENERGY_MAX, VIEW_ENERGY_CONSUME, \
    HERBIVORE_COLOR, PLANT_COLOR, CARNIVORE_COLOR
from per.mnxc.survival_evolution.po.space_grid import SpaceGrid


# 生物基类
class Organism(pygame.sprite.Sprite):
    def __init__(self, x: float, y: float, speed_max: float = 1, energy: float = 100,
                 color: str = '#aaa', view: float = 50):
        super().__init__()
        # 设置精灵的图像和矩形
        self.image = pygame.Surface((50, 50))
        self.x: float = clamp(x, min=0, max=WORLD_WIDTH)
        self.y: float = clamp(y, min=0, max=WORLD_HEIGHT)
        self.vx: float = 0
        self.vy: float = 0
        self.speed_max = clamp(speed_max, min=0, max=SPEED_MAX)
        self.energy = clamp(energy, min=0, max=ENERGY_MAX)
        self.color = color
        self.view = clamp(view, min=0, max=VIEW_MAX)
        self.speed: float = 0
        self.angle: float = 0
        # 子代
        self.children: list[Organism] = []
        # 生物是否存活
        self.is_alive: bool = True

    # 生物更新 delta_time: float 单位：秒
    def update(self, delta_time: float, space_grid: SpaceGrid):
        # 生物基本的生存能量消耗
        self.energy -= delta_time * ENERGY_CONSUME
        # 生物的运动能量消耗
        self.energy -= delta_time * min(self.speed, 0) * ENERGY_CONSUME
        # 生物感知能量消耗
        self.energy -= delta_time * self.view * VIEW_ENERGY_CONSUME
        # 生物的基本移动
        self.vx = self.speed * math.cos(self.angle)
        self.vy = self.speed * math.sin(self.angle)
        self.x += self.vx * delta_time
        self.y += self.vy * delta_time
        if self.energy <= 0:
            self.energy = 0
            # 死亡
            self.kill()

    def draw(self, screen: pygame.Surface):
        pygame.draw.circle(screen, self.color, (self.x, self.y), 5)

    def kill(self):
        self.is_alive = False
        super().kill()

    def get_children_num(self) -> int:
        l = len(self.children)
        for child in self.children:
            if len(child.children) > 0:
                l += child.get_children_num()
        return l

# 动物基类
class Animal(Organism):
    def __init__(self, x: float, y: float, brain, speed_max: float = 1, energy: float = 100,
                 color: str = '#666', view: float = 50):
        super().__init__(x, y, speed_max, energy, color, view)
        self.brain = brain

    def update(self, delta_time: float, space_grid: SpaceGrid):
        action = self.get_action(self.get_state(space_grid))
        super().update(delta_time)

    def eat(self, food: Organism):
        self.energy += food.energy * ENERGY_CONVERT
        food.kill()

    def reproduce(self) -> 'Animal':
        # 生成子代
        pass

    def get_state(self, space_grid: SpaceGrid) -> list[float]:
        # 环境状态 -> 用于训练和输入到神经网络
        pass

    def get_action(self, state: list[float]) -> (float, float):
        # 获取动作 -> 用于训练和输入到神经网络
        pass

    def find_food(self) -> Organism:
        # 寻找食物
        pass

    def draw(self, screen: pygame.Surface):
        super().draw(screen)
        # 画出可视范围 颜色为自身的颜色，透明度为0.5
        pygame.draw.circle(screen, self.color, (self.x, self.y), self.view, 1)
        # 画出一双眼睛，眼睛朝向移动的方向
        pygame.draw.line(screen, self.color, (self.x, self.y), (self.x + self.view * math.cos(self.angle),
                                                                self.y + self.view * math.sin(self.angle)), 1)


class Plant(Organism):
    """植物类"""
    def __init__(self, x: float, y: float):
        super().__init__(x, y, speed_max=0, energy=PLANT_ENERGY_INIT, color=PLANT_COLOR, view=0)

    def update(self, delta_time: float):
        # 植物进行光合作用
        self.energy += (delta_time / 1000.0) * PLANT_ENERGY_CONSUME
        super().update(delta_time)


class Herbivore(Animal):
    """食草动物"""
    def __init__(self, x: float, y: float, brain, view: float = 50):
        super().__init__(x, y, brain, color=HERBIVORE_COLOR,speed_max=1.5, view=view)

    def find_food(self) -> Organism:
        # 在视野范围内寻找最近的植物
        pass

    def eat(self, food: Plant):
        if isinstance(food, Plant):
            super().eat(food)


class Carnivore(Animal):
    """食肉动物"""
    def __init__(self, x: float, y: float, brain, view: float = 50):
        super().__init__(x, y, brain, color=CARNIVORE_COLOR, speed_max=2.0)

    def find_food(self) -> Organism:
        # 在视野范围内寻找最近的食草动物
        pass

    def eat(self, food: Herbivore):
        if isinstance(food, Herbivore):
            super().eat(food)